package com.yzion.baselib.http

import okhttp3.OkHttpClient
import retrofit2.Retrofit
import java.util.*
import java.util.concurrent.TimeUnit
import kotlin.collections.ArrayList

/**
 * 接口创建帮助类，基于retrofit2+okhttp3的统一配置封装，方便快速开发，
 * 快速使用可见BaseApi，其内部使用ApiHelper创建ApiService
 */
class ApiHelper private constructor() {

    //接口地址对应的Http配置实例
    val baseApiConfigMap: MutableMap<String, BaseApiConfig> = HashMap()

    //接口地址对应的Retrofit实例
    val retrofitMap: MutableMap<String, Retrofit> = HashMap()

    //接口地址对应的OkHttpClient实例
    val httpClientMap: MutableMap<String, OkHttpClient> = HashMap()

    val baseUrlList = LinkedHashSet<String>()

    /**
     * 使用默认配置创建接口服务
     */
    fun <S> create(baseUrl: String, service: Class<S>): S {
        return get().createRetrofit(baseUrl).create(service)
    }

    /**
     * 使用自定义默认配置创建接口服务
     */
    fun <S> create(baseUrl: String, service: Class<S>, config: BaseApiConfig): S {
        return get().createRetrofit(baseUrl, config).create(service)
    }

    private val defaultBaseApiConfig: BaseApiConfig
        get() = object : BaseApiConfig() {
            override fun configResponseSuccessCode() = "0"
        }

    private fun createRetrofit(
        baseUrl: String,
        config: BaseApiConfig = defaultBaseApiConfig
    ): Retrofit {
        if (retrofitMap[baseUrl] != null) {
            return retrofitMap[baseUrl]!!
        }
        val okHttpClient = getClient(baseUrl, config)
        val builder = Retrofit.Builder()
            .baseUrl(baseUrl)
            .client(okHttpClient)

        config.configRetrofit(builder)

        val retrofit = builder.build()
        baseUrlList.add(baseUrl)
        retrofitMap[baseUrl] = retrofit
        httpClientMap[baseUrl] = okHttpClient
        baseApiConfigMap[baseUrl] = config
        return retrofit
    }

    private fun getClient(baseUrl: String, config: BaseApiConfig): OkHttpClient {
        if (httpClientMap[baseUrl] != null) {
            return httpClientMap[baseUrl]!!
        }
        val builder = OkHttpClient.Builder()

        //配置连接超时
        builder.connectTimeout(config.configConnectTimeoutMills(), TimeUnit.MILLISECONDS)

        //配置读取数据超时
        builder.readTimeout(config.configReadTimeoutMills(), TimeUnit.MILLISECONDS)

        //配置cookie
        val cookieJar = config.configCookie()
        builder.cookieJar(cookieJar)

//        //配置进度事件
//        if (config.configProgressEnable()) {
//            builder.addInterceptor(ProgressHelper.get().interceptor)
//        }

        //配置自定义应用拦截器
        val interceptors = config.configInterceptors()
        if (interceptors != null) {
            for (interceptor in interceptors) {
                builder.addInterceptor(interceptor)
            }
        }

        //配置连接失败重试次数
//        if (config.configRetryTime() != 0) {
//            //连接失败时重试
//            builder.retryOnConnectionFailure(true);
//            builder.addInterceptor(new RetryInterceptor(config.configRetryTime()));
//        }

        //配置log
        if (config.configLogEnable()) {
            builder.addNetworkInterceptor(config.configLogInterceptor())
        }

        //还需要其他配置，可自行配置，例如https,
        config.configOkHttpClient(builder)

        val client = builder.build()
        httpClientMap[baseUrl] = client
        baseApiConfigMap[baseUrl] = config
        return client
    }

    /**
     * 通过接口地址获取对应的OkHttpClient实例
     */
    fun getOkHttpClient(baseUrl: String): OkHttpClient? {
        return httpClientMap[baseUrl]
    }

    /**
     * 通过接口地址获取对应的Retrofit实例
     */
    fun getRetrofit(baseUrl: String): Retrofit? {
        return retrofitMap[baseUrl]
    }

    /**
     * 通过接口地址获取对应的HttpConfig实例
     */
    fun getHttpConfig(baseUrl: String): BaseApiConfig? {
        return baseApiConfigMap[baseUrl]
    }

    companion object {
        private val apiHelper: ApiHelper by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            ApiHelper()
        }

        @JvmStatic
        fun get(): ApiHelper {
            return apiHelper
        }
    }
}